import * as React from "react";
import * as monacoGlobal from "monaco-editor";
import SplitPane from "react-split-pane";

import { EditorPane } from "./EditorPane";
import { GraphPane } from "./GraphPane";
import { SupportedFormat, SupportedEngine } from "../rendering";
import { getSplitConfig, saveSplitConfig } from "../config";

type ErrorList = monacoGlobal.editor.IMarkerData[];

interface Props {
	initialSource: string;
	format: SupportedFormat;
	engine: SupportedEngine;
	onSourceChange?(source: string): void;
}

type State = SourceState | ErroredState;
interface SourceState {
	dotSrc: string;
	errors: undefined;
	lastKnownGoodSrc: undefined;
}
interface ErroredState {
	dotSrc: undefined;
	errors: ErrorList;
	lastKnownGoodSrc?: string;
}

const createSourceState = (dotSrc: string): SourceState => ({ dotSrc, errors: undefined, lastKnownGoodSrc: undefined });
const createErroredState = (errors: ErrorList, lastKnownGoodSrc?: string): ErroredState => ({ dotSrc: undefined, errors, lastKnownGoodSrc });

export default class SplitEditor extends React.Component<Props, State> {

	private editorPaneRef: React.RefObject<EditorPane> = React.createRef();

	constructor(props: Props) {
		super(props);
		const p = this.props;

		this.state = createSourceState(p.initialSource);
		if (p.onSourceChange)
			p.onSourceChange(this.state.dotSrc);
	}

	public loadDotSource(dotSrc: string) {
		// Change the value of the underlying monaco instance
		// Monaco will call onChange and
		// the rest is going to be handled as if the user changed the value by hand
		const editor = this.editorPaneRef.current;
		if (editor) {
			editor.loadValue(dotSrc);
		}
	}

	dotSourceChanged = (dotSrc: string): void => {
		const p = this.props;
		if (p.onSourceChange)
			p.onSourceChange(dotSrc);

		this.setState(createSourceState(dotSrc));
	}

	dotSourceErrored = (errors: ErrorList): void => {
		this.setState(prevState => {
			const lastKnownGoodSrc = prevState.dotSrc || prevState.lastKnownGoodSrc;
			return createErroredState(errors, lastKnownGoodSrc);
		});
	}

	private getDotSrcToRender() {
		const s = this.state;

		return !!s.dotSrc
			? s.dotSrc
			: (s.lastKnownGoodSrc ? s.lastKnownGoodSrc : "");
	}
	private changeNodeValue() {
		const that = this;
		interface ChangeValue {
			oneValue: string, // 鼠标点击第一个值
			twoValue: string, // 鼠标点击第二个值
			isComplete: Boolean // 是否这个已经完成，如果已经完成，就把上面两个值清空
		}
		let changeValue:ChangeValue = { // 改变的值
			oneValue: '', // 鼠标点击第一个值
			twoValue: '', // 鼠标点击第二个值
			isComplete: false // 是否这个已经完成，如果已经完成，就把上面两个值清空
		}
		let oldValue:any = undefined; // 上一次点击的值，防止用户重复点击
		let stepNum:number = 0; //默认0，完成第一个值，就是1
		// 获取所有 class 为 node 的节点
		const clickTimeout = setTimeout( ()=>{
			const nodeElements = document.querySelectorAll('.node');
			window.clearTimeout(clickTimeout)
			// 为每个节点添加点击事件监听器
			nodeElements.forEach((node) => {
				node.addEventListener('click', () => {
					// that.setState(createSourceState(dotSrc));
					if(stepNum === 2){
						changeValue.oneValue = '';
						changeValue.twoValue = '';
						stepNum = 0;
					}
					// 获取节点内的 title 元素
					const titleElement = node.querySelector('title');
					if (titleElement) {
						// 提取 title 元素的文本内容
						const titleValue = titleElement.textContent;
						if(titleValue !== oldValue ){
							if(stepNum === 0){
								if (typeof titleValue === "string") {
									changeValue.oneValue = titleValue
									oldValue = titleValue
									stepNum = 1
								}
								alert('获取初始线成功')
							}else if(stepNum === 1){
								if (typeof titleValue === "string") {
									changeValue.twoValue = titleValue
									oldValue = titleValue
									stepNum = 2
								}
								let _dotSrc:any = that.state.dotSrc
								// 使用正则表达式提取颜色值
								const colorRegex = /color="([^"]+)"/;
								const match = _dotSrc.match(colorRegex);
								let color;
								if (match) {
									color = match[1];
								} else {
									// 如果未匹配到颜色值，可设置默认颜色
									color = '#000000';
								}

								// 构建新的边信息
								const newEdge = `\t${changeValue.oneValue} -- ${changeValue.twoValue} [color="${color}"]\n`;

								// 在 dotSrc 字符串的倒数第二个字符（即 '}' 之前）插入新的边信息
								_dotSrc = _dotSrc.slice(0, -2) + newEdge + _dotSrc.slice(-2);

								alert('获取终止线成功')
								const setDotInfo = setTimeout(()=>{
									window.clearTimeout(setDotInfo);
									that.setState(createSourceState(""));
									that.setState(createSourceState(_dotSrc));

									const changeB = setTimeout(() => {
										window.clearTimeout(changeB);
										debugger
										that.changeNodeValue();
									}, 200);
								},1800)

							}

						}
					}
					console.log(changeValue)
				});
			});
		},1000)
	}

	public componentDidMount() {
		this.changeNodeValue()

	}

	public render() {
		const s = this.state;
		const p = this.props;
		const that = this



		const isErrored = s.errors && s.errors.length > 0;
		const dotSrc = this.getDotSrcToRender();

		console.log('dotSrcsssss')
		console.log(dotSrc)

		var messageHandle = function(e:any) {
			console.log('接受到的信息是：' + e.data)
			// let dotSrc = e.data.toString()
			let dotSrc22 = encodeURIComponent(`"# Place the cursor inside "graph" to get some refactoring options

			graph {

				# To refactor nodes, place the cursor left to a node name
				a -- b
				a -- c;
				a -- d;
				a -- b;
				a -- ec;

				# Hover over color names to get a color picker
				b -- b [color=blue]
				b -- d [color="#ff0000"];

				# Get completion when assigning a shape or color
				b [shape=box, color=yellow];

				a; # You can remove optional ; by placing the cursor left to a semicolon
			}
			"`)
			that.setState(createSourceState(dotSrc));
		};
		if (window.addEventListener) {
			// 接受信息
			window.addEventListener("message", messageHandle, false);
		}
		console.log('this.state.dotSrc', dotSrc)
		console.log('this.state.dotSrc', s.dotSrc)


		const graphPaneClass = isErrored ? "errored" : "successful";

		return (
			<SplitPane
				split="vertical"
				minSize={50}
				defaultSize={getSplitConfig() || "50%"}
				onChange={size => saveSplitConfig(size)}
			>
				<EditorPane
					ref={this.editorPaneRef}
					defaultValue={s.dotSrc}
					onChangeValue={this.dotSourceChanged}
					onValueError={this.dotSourceErrored}
				/>

				<
					GraphPane className={"graph-container " + graphPaneClass}
							  dotSrc={dotSrc}
							  engine={p.engine}
							  format={p.format}
				/>
			</SplitPane>
		);
	}
}
